import { EventsRes, ICurve, SceneGraph } from '@amcax/base';
import { ctx2 } from '@app-cad/module';
import { wsApi } from '@app-cad/server';
import { Vector3 } from 'three-legacy';
import {
  SKETCH_CENTEREVENTS,
  sketchEventCenter,
  // USER_EVENTS,
} from '../../../events/SketchEventCenter';
import CmdBase from '../../CmdBase';
import { MouseState, SketchReturn, State } from './types';
import { Vector2Tuple } from 'three/src/Three.Core.js';
import { renderSketch } from '@app-base/common/utils';

export class CmdInteractor extends CmdBase {
  point: Vector3;
  currentState: MouseState = State.DRAW;
  // 草图数据
  public sketchData: ICurve[];

  constructor() {
    super();
    this.registerEvents();
    // this.init();
  }

  public registerEvents() {
    sketchEventCenter()
      .setState('point')
      .on(SKETCH_CENTEREVENTS.POINTERMOVE, this.onPointMove)
      .on(SKETCH_CENTEREVENTS.POINTERUP, this.onPointUp)
      .on(SKETCH_CENTEREVENTS.KEYUP, this.onKeyUp)
      .addExit(this.destroy.bind(this));
  }

  public unregisterEvents() {
    sketchEventCenter()
      .off(SKETCH_CENTEREVENTS.POINTERMOVE, this.onPointMove)
      .off(SKETCH_CENTEREVENTS.POINTERUP, this.onPointUp)
      .off(SKETCH_CENTEREVENTS.KEYUP, this.onKeyUp)
      .setDefault();
  }

  onPointMove = async (e: EventsRes) => {
    this.setMouseWV(e, true);
    this.point = this.mouseWV.clone();
    this.picker.pickMulti(e, { line: true });
  };

  onPointUp = (e: EventsRes) => {
    if (e.button.onLeft) {
      if (this.currentState === State.DRAW) {
        this.currentState = State.FINISH;
        this.createPoint();
        // this.destroy();
        this.releaseObjects();
        this.reset();
      }
    } else if (e.button.onRight) {
      // this.destroy();
    }
  };

  async createPoint() {
    const point: Vector2Tuple = [this.point.x, this.point.y];

    const res: SketchReturn = await wsApi.createSketchPoint(this.sketchId, {
      point,
      constraints: this.getPointConstraintsFromSnapResult(
        this.currentSnapInfo,
        point,
        true,
      ),
    });

    await renderSketch(this.sketchId, res);
    return res;
  }

  reset() {
    this.currentState = State.DRAW;
    this.point = null;
  }

  releaseObjects() {
    this.assisGroup.clear();
    SceneGraph.emptyGroup(this.assisGroup);
    ctx2.viewer.requestRender();
  }
}
